package com.cee.util;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.NumberFormat;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringUtil {

    public static final String AND = "&";
    public static final String EQUAL = "=";
    private static final int SRC_LENGHT = 3;
    private static final int NUM_0 = 0;
    private static final int NUM_2 = 2;

    public static String filterSpecialCharacter(String src) {
        if (src == null) {
            return null;
        }

        return src.replaceAll("[^0-9a-zA-Z]+", "");
    }

    public static final char UNDERLINE = '_';

    public static String camelToUnderline(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c)) {
                sb.append(UNDERLINE);
                sb.append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString().trim();
    }

    public static String underlineToCamel(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (c == UNDERLINE) {
                if (++i < len) {
                    sb.append(Character.toUpperCase(param.charAt(i)));
                }
            } else {
                sb.append(c);
            }
        }
        return sb.toString().trim();
    }

    public static String underlineToCamel2(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        StringBuilder sb = new StringBuilder(param);
        Matcher mc = Pattern.compile("_").matcher(param);
        int i = 0;
        while (mc.find()) {
            int position = mc.end() - (i++);
            // String.valueOf(Character.toUpperCase(sb.charAt(position)));
            sb.replace(position - 1, position + 1, sb.substring(position, position + 1).toUpperCase());
        }
        return sb.toString().trim();
    }

    public static String formatAsUrlParamString(Map<String, Object> source) {
        Iterator<String> it = source.keySet().iterator();
        StringBuilder paramStr = new StringBuilder();
        while (it.hasNext()) {
            String key = it.next();
            if (source.get(key) == null) {
                continue;
            }
            paramStr.append(AND).append(key).append(EQUAL).append(source.get(key));
        }
        // 去掉第一个&
        return paramStr.substring(1);
    }

    /**
     * Trim the parameter 清除字符串空格.
     *
     * @param str str
     * @return String
     */
    public static String trimToNull(String str) {
        if (StringUtils.isBlank(str)) {
            return null;
        }
        return str.trim();
    }

    /**
     * trim object to empty
     *
     * @param obj obj
     * @return String
     */
    public static String trimToEmpty(Object obj) {
        if (obj == null) {
            return "";
        } else {
            return obj.toString().trim();
        }
    }

    public static String substring(String str, int startIndex, int len) {
        if (StringUtils.isEmpty(str)) {
            return null;
        } else {
            // subString("abcd", 0, 2) = "ab"
            return StringUtils.substring(str, startIndex, startIndex + len);
        }
    }

    public static String substring(String str, int maxLength) {
        int startIndex = 0;
        if (StringUtils.isEmpty(str)) {
            return null;
        } else {
            return StringUtils.substring(str, startIndex, startIndex + Math.min(str.length(), maxLength));
        }
    }

    /**
     * trimForDBSelect.
     *
     * @param src src
     * @return String
     */
    public static String trimForDBSelect(String src) {
        if (src == null) {
            return null;
        }
        String result = src.trim().replace(" ", "").toUpperCase();
        return StringUtils.isEmpty(result) ? null : result;
    }

    /**
     * 删除不包括星号在内的特殊字符.
     *
     * @param src src
     * @return String
     */
    public static String removeSpecialCharacter(String src) {
        if (src == null) {
            return null;
        }
        return src.replaceAll("[^0-9a-zA-Z*]+", "");
    }

    /**
     * 字符串设置为Empty
     *
     * @param src
     */
    public static String stringToEmpyt(String src) {
        if (StringUtils.isBlank(src)) {
            return "";
        }
        return src;
    }

    /**
     * convertAvailSlotListToString.
     *
     * @param availSlotList availSlotList
     * @return String
     */
    public static String convertAvailSlotListToString(List<int[]> availSlotList) {
        String returnValue = "";
        for (int[] la24HoursSlot : availSlotList) {
            returnValue = String.format("%s%s", returnValue, intArrayToStringForTimeSlot(la24HoursSlot));
        }
        return returnValue;
    }

    /**
     * intArrayToStringForTimeSlot
     *
     * @param la24HoursSlot la24HoursSlot
     * @return String
     */
    private static String intArrayToStringForTimeSlot(int[] la24HoursSlot) {
        if (la24HoursSlot == null || la24HoursSlot.length == 0) {
            return "";
        }
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < la24HoursSlot.length; i++) {
            String value = Integer.toString(la24HoursSlot[i]);
            while (value.length() < SRC_LENGHT) {
                value = "0" + value;
            }
            buffer.append(value);
        }
        return buffer.toString();
    }

    /**
     * 转换大写.
     *
     * @param src String
     * @return String
     */
    public static String toUpperCase(String src) {
        if (src == null || "".equals(src)) {
            return null;
        }
        return src.trim().toUpperCase();
    }

    /**
     * String右对齐
     *
     * @param src src
     * @param len len
     * @param ch  ch
     * @return String
     */
    public static String padRight(String src, int len, char ch) {
        int diff = len - src.length();
        if (diff <= 0) {
            return src;
        }

        char[] charr = new char[len];
        System.arraycopy(src.toCharArray(), 0, charr, 0, src.length());
        for (int i = src.length(); i < len; i++) {
            charr[i] = ch;
        }
        return new String(charr);
    }

    /**
     * String左对齐.
     *
     * @param src src
     * @param len len
     * @param ch  ch
     * @return String
     */
    public static String padLeft(String src, int len, char ch) {
        int diff = len - src.length();
        if (diff <= 0) {
            return src;
        }

        char[] charr = new char[len];
        System.arraycopy(src.toCharArray(), 0, charr, diff, src.length());
        for (int i = 0; i < diff; i++) {
            charr[i] = ch;
        }
        return new String(charr);
    }

    public static String getContent(InputStream inputStream) {
        try {
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            IOUtils.copy(inputStream, output);
            return new String(output.toByteArray());
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
    }

    public static String getPercentStr(double d, int maximumFractionDigits) {
        NumberFormat nf = NumberFormat.getPercentInstance();
        nf.setMaximumFractionDigits(maximumFractionDigits);
        return nf.format(d);
    }

    /**
     * 截取字数字字符串并转换为int类型.
     *
     * @param value      字符串值
     * @param startIndex 开始索引
     * @param length     截取长度
     * @return 返回int类型
     */
    public static int substringParseInt(String value, int startIndex, int length) {
        try {
            return Integer.parseInt(Objects.requireNonNull(StringUtil.substring(value, startIndex, length)));
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    /**
     * 字符串不為空.
     *
     * @param value String value
     * @return boolean
     */
    public static boolean isNotNull(String value) {
        return !isNull(value);
    }

    /**
     * 字符串為空.
     *
     * @param value String value
     * @return boolean
     */
    public static boolean isNull(String value) {
        return Objects.isNull(value);
    }

    /**
     * 替換內容.
     *
     * @param oldValue 旧字符串
     * @param newValue 新字符串
     * @return oldValue為空切newValue不為空，則替換為newValue
     */
    public static String replaceContent(String oldValue, String newValue) {
        if (StringUtils.isNotBlank(oldValue) && StringUtils.isNotBlank(newValue)) {
            return newValue;
        }
        return oldValue;
    }


    /**
     * 比较两个字符串时间HHmm.
     * 如果oldTime等于newTime或者在newTime之后，返回true
     *
     * @param oldTime 旧时间值
     * @param newTime 新时间值
     * @return boolean
     */
    public static boolean compareTimeSize(String oldTime, String newTime) {
        if (Objects.isNull(trimToNull(oldTime)) || Objects.isNull(trimToNull(newTime))) {
            return false;
        }
        if (StringUtils.equals(oldTime, newTime)) {
            return true;
        }
        int oldHour = substringParseInt(oldTime, NUM_0, NUM_2);
        int oldMinute = substringParseInt(oldTime, NUM_2, NUM_2);
        int newHour = substringParseInt(newTime, NUM_0, NUM_2);
        int newMinute = substringParseInt(newTime, NUM_2, NUM_2);

        return oldHour == newHour && oldMinute >= newMinute;
    }
}
